#include "type.h"
#include "message.h"
#include "protect.h"
#include "pic.h"
#include "clock.h"
int ticks;
void dispStr(char*);	
void none(void);
void schedule();
void out_byte(u16,u8);
static struct process* p_head; //进程调度头节点
static struct process* p_tail; //进程调都尾节点

void init_schedule(void);

void list_insert(struct process*);

void list_delete_add(void);
/*
* init 8053 chip
*/
void init_clock(){
	out_byte(TIMER_MODE,MODE3);
	out_byte(TIMER0,(u8)(TIMER_FRE/HZ));
	out_byte(TIMER0,(u8)((TIMER_FRE/HZ)>>8));
}
int get_ticks(){
	return ticks;
}
void delay_mill(u32 mill){
//every 10ms per interrupt 
	int ticks=get_ticks();
	while((get_ticks()-ticks)*10<mill)
		;
}
void clock_handler(){
	ticks++;
	schedule();
	out_byte(0x20,EOI);	
}
/**
*初始化双链表
**/
void init_schedule(void){
	struct process* p;
	for(p=p_process;p<p_process+MAX_NUM-1;p++) //将链表的下一链表链接起来
		p->next=p+1;
	for(p=p_process+MAX_NUM-1;p>p_process;p--) //将链表的上一链表链接起来
		p->prev=p-1;
	p_head=p_process; //设置头节点	
	p_tail=p_process+MAX_NUM-1;//设置尾节点
}
/**
*双链表的插入
**/
void list_insert(struct process* p_node){
	//如果链表为空
	if(!p_head){
		p_head=p_node;
		p_node->prev=NULL_PROC;
		p_node->next=NULL_PROC;
		p_tail=p_node;
	}else{
		p_node->next=p_head;
		p_head->prev=p_node;
		p_head=p_node;
	}		
}
/**
*双链表的删除和重安排
**/
void list_delete_add(){
	struct process* p;
	if(!p_head)
		return;
	else{
	//将链表的第一个节点删除然后添加到结尾
		p=p_head;
		p_head->next->prev=NULL_PROC;
		p_head=p_head->next;
		p->prev=p_tail;
		p_tail->next=p;
		p->next=NULL_PROC;
		p_tail=p;
		p->counter=120;
	}	
}
/**
*将当前的阻塞进程移到链表尾 
**/
void block_arrange(void){
	struct process* p;
	if(!p_head)
		return;
	else{
		p=p_head;
		p_head->next->prev=NULL_PROC;
		p_head=p_head->next;
		p->prev=p_tail;
		p_tail->next=p;
		p->next=NULL_PROC;
		p_tail=p;
	}		
}
/**
* 			时钟调度算法(开始)
**/
static struct process* clock_head;
//初始化时钟调度算法
void init_clock_schedule(void){
	struct process* p;
	/**
	*将进程表链接成循环单链表
	*
	**/
	for(p=p_process;p<p_process+MAX_NUM-1;p++){
		p->next=p+1;
	}
	p->next=p_process;
	//设置时钟头
	clock_head=p_process;
}
//在循环链表向前移动一位
void advance_proc(void){
	if(!clock_head)
		dispStr("kernel error no active proc \n");
	else
		clock_head=clock_head->next;
	if(clock_head->counter<=0)	
		clock_head->counter=120;	
}
//主动阻塞当前进程
void block_proc(void){
	if(!clock_head)
		dispStr("kernel error no proc \n");
	else{	
		clock_head=clock_head->next;
//		clock_head->state=BLOCK;
	}
}
/**
*			时钟调度算法(结束)
**/
void schedule(){
//	cur;
//	cur=p_head;
	cur=clock_head;
//	dispStr(cur->name);
//	dispStr("hello\n");
	if(cur->state==BLOCK){
		dispStr("<");
		dispStr(cur->name);
		dispStr(">");
//		dispStr("->blocked\n");
	}
	while(cur->state==BLOCK||!cur->counter){ //找到状态不为阻塞的进程
	//	list_delete_add();
		//如果当前进程被阻塞或者时间片用完了
		//选择下一进程
		advance_proc();
	//	cur=p_head;
		cur=clock_head;
	}
	cur->counter-=1;
}
